<template>
  <div class="community community-floor">
    <div class="community-list waterfall" ref="cardRef">
      <div
        class="community-item waterfall-item"
        v-for="(item, index) in communityList"
        :key="index"
        :style="{ width: cardWidth + 'px' }"
        :ref="
          (el) => {
            waterfallList[index] = el;
          }
        "
      >
        <div class="author-info">
          <div class="author-avatar">
            <img src="/logo.png" alt="" class="avatar fit-cover" />
          </div>
          <div class="author-name">{{ item.name }}</div>
          <div class="publish-time">
            {{ parseDateArrayToDateString(item.createTime) }}
          </div>
        </div>
        <div class="community-content">
          <a @click="handleToPost(item.id)" v-if="item.postTitle" class="title">
            {{ item.postTitle }}
          </a>
          <div
            v-if="item.postContent"
            style="margin-top: 0.5rem"
            class="content"
          >
            {{ item.postContent }}
          </div>
        </div>
        <div class="cover">
          <a
            class="img-container"
            data-fancybox="gallery"
            v-for="cover in item.coverList"
            :href="cover"
            :key="cover"
          >
            <img v-if="checkImage(cover)" @load="resetPosition" :src="cover" />
            <video v-else :src="cover" @load="resetPosition"></video>
          </a>
        </div>
        <div class="meta-info"></div>
      </div>
    </div>
    <div
      v-if="!isOver"
      ref="loadingRef"
      style="text-align: center; margin-top: 1rem"
    >
      {{ isLoadingData ? "正在加载..." : "下滑加载更多数据" }}
    </div>
    <div v-else ref="loadingRef" style="text-align: center; margin-top: 1rem">
      数据全部加载完毕
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from "vue";
import { getCommunityList } from "@/api/post";
import { useRouter } from "vue-router";
import { parseDateArrayToDateString } from "@/utils/common";

const communityList = ref<Community[]>([]);

const loadingRef = ref();

const cardWidth = ref(0);

const cardRef = ref();

const router = useRouter();

const isOver = ref<boolean>(false);

const isLoadingData = ref<boolean>(false);

const pageInfo = {
  pageNum: 1,
  pageSize: 10,
};

const columnHeight = ref(new Array(communityList.value.length).fill(0));
const waterfallList = ref<any[]>([]);

const checkImage = (cover: string) => {
  return /\.(jpg|jpeg|png|gif|svg|webp)$/i.test(cover);
};

const resetPosition = async () => {
  cardWidth.value =
    (cardRef.value.clientWidth -
      (waterFallParams.columns - 1) * waterFallParams.columnGap) /
    waterFallParams.columns;
  columnHeight.value = new Array(waterFallParams.columns).fill(0);
  for (let i = 0; i < waterfallList.value.length; i++) {
    const index = getMinColumnHeightIndex();
    waterfallList.value[i].style.top = `${columnHeight.value[index]}px`;
    waterfallList.value[i].style.left = `${
      index * (cardWidth.value + waterFallParams.columnGap)
    }px`;
    columnHeight.value[index] =
      columnHeight.value[index] +
      waterfallList.value[i].clientHeight +
      waterFallParams.rowGap;
  }
  cardRef.value.style.height = `${Math.max(...columnHeight.value)}px`;
};

const getMinColumnHeightIndex = () => {
  return columnHeight.value.reduce((prev, curr, index) => {
    return curr < columnHeight.value[prev] ? index : prev;
  }, 0);
};

const waterFallParams = {
  columns: 2,
  columnGap: 20,
  rowGap: 10,
};

const handleToPost = (postId: number) => {
  router.push({
    path: "/community",
    query: {
      postId,
    },
  });
};

const parseImages = (imgs: string) => {
  return imgs.split(",").filter(Boolean);
};

const handleGetCommunityList = async (
  pageNum: number = 1,
  pageSize: number = 10
) => {
  const result = await getCommunityList(pageNum, pageSize);
  if (result.data.code === 200) {
    const list = result.data.data;
    list.forEach((item: any) => {
      item.coverList = parseImages(item.cover);
    });
    communityList.value.push(...list);
    communityList.value = communityList.value.sort((a, b) => {
      return (
        //@ts-ignore
        new Date(...b.createTime).getTime() -
        //@ts-ignore
        new Date(...a.createTime).getTime()
      );
    });
    resetPosition();
  }
};

onMounted(async () => {
  isLoadingData.value = true;
  await handleGetCommunityList();
  isLoadingData.value = false;
  resetPosition();
  // setInterval(() => {
  //   resetPosition();
  // }, 1000);
  window.onscroll = async () => {
    resetPosition();
    if (loadingRef.value) {
      if (
        loadingRef.value.getBoundingClientRect().bottom + 10 <
        window.innerHeight
      ) {
        pageInfo.pageNum++;
        isLoadingData.value = true;
        const list = await getCommunityList(pageInfo.pageNum);
        if (list.data.data.length === 0) {
          isOver.value = true;
          window.onscroll = null;
          return;
        }
        let result = list.data.data;
        result.forEach((item: any) => {
          item.coverList = parseImages(item.cover);
        });
        communityList.value.push(...result);
        resetPosition();
      }
    }
  };
});
</script>

<style scoped lang="scss">
.community-floor {
  width: 100%;
  overflow: hidden;
  height: fit-content;

  .community-list {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    position: relative;
    justify-content: space-between;
    align-items: flex-start;
    align-content: flex-start;
    -webkit-user-select: none;
    user-select: none;

    .community-item {
      flex-direction: column;
      flex: 1 1 40%;
      box-shadow: var(--xz-shadow-border);
      display: flex;
      -webkit-box-orient: horizontal;
      -webkit-box-align: center;
      transition: all 0.3s ease 0s;
      position: absolute;
      overflow: hidden;
      will-change: transform;
      width: 100%;
      max-width: 50%;
      user-select: none;
      height: fit-content;
      background: var(--xz-card-bg);
      border-radius: 12px;
      cursor: pointer;
      border: var(--style-border);
      padding: 1rem;
      position: absolute;

      &:hover {
        border: var(--style-border-hover);
      }

      .author-info {
        display: flex;
        align-items: center;
        margin-bottom: 1rem;
        position: relative;

        .author-avatar {
          height: 30px;
          width: 30px;
          border-radius: 50%;
          overflow: hidden;
          margin-right: 0.5rem;

          .img {
            height: 30px;
            width: 30px;
          }
        }

        .author-name {
          font-size: 1rem;
          font-weight: 500;
        }

        .publish-time {
          position: absolute;
          right: 1rem;
        }
      }

      .community-content {
        margin-bottom: 1rem;

        .title {
          font-size: 1.2rem;
          font-weight: 500;
        }
      }

      .cover {
        display: flex;
        flex-wrap: nowrap;
        gap: 0.5rem;

        .img-container {
          min-width: 33.33%;
          max-width: 50%;
          height: 120px;

          img,
          video {
            max-width: 100%;
            max-height: 100%;
            width: 100%;
            height: 100%;
            object-fit: cover;
          }
        }
      }
    }
  }
}

.waterfall {
  width: 100%;
  position: relative;

  .waterfall-item {
    position: absolute;
  }
}
</style>
